package com.concurrent.synchronizeandreentrant;


import java.util.concurrent.*;

/**
 * @ClassName: MyThreadPoolExecutor
 * @Description: TODO
 * @author: li
 * @Date: 2021/8/17 6:31 下午
 */
public class MyThreadPoolExecutor {
    public static void main(String[] args) {

        // 核心线程数量
        int corePoolSize = 3;
        // 最大线程数量
        int maximumPoolSize = 6;
        // 非核心线程的空闲状态下的存活时间（如果池中当前有多于corePoolSize的线程，则这些多出的线程在空闲时间超过keepAliveTime时将会终止）
        long keepAliveTime = 2;
        // 时间单位（以秒为时间单位）
        TimeUnit timeUnit = TimeUnit.SECONDS;
        // 工作队列，用于存放等待执行的任务
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor threadPoolExecutor = null;
        try {
            threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue, new ThreadPoolExecutor.AbortPolicy());

            for (int i = 0; i < 9; i++) {
                final int index = (i + 1);
                // 返回一个Future对象，该对象可以或获取Callable任务的返回值，通过get方法。
                Future<?> future = threadPoolExecutor.submit(() -> {
                    {
                        System.out.println("这是任务：" + index);
                        try {
                            //模拟线程执行时间
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
                // 通过执行该线程的cancel方法可以中断该线程。
//                 future.cancel(true);

                Thread.sleep(500);
            }


        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (RejectedExecutionException e) {
            System.out.println("拒绝执行异常：因为无可用线程");
        } finally {
            assert threadPoolExecutor != null;
            // shutdown() 方法会等待线程都执行完毕之后再关闭
            threadPoolExecutor.shutdown();
            // shutdownNow 会给每个线程发送interrupt信号，
//            threadPoolExecutor.shutdownNow();
        }
    }


    /**
     * 执行结果
     * 这是任务：1
     * 这是任务：2
     * 这是任务：3
     * 这是任务：6
     * 这是任务：7
     * 这是任务：8
     * 这是任务：4
     * 这是任务：5
     *
     */

    /**
     * 执行结果分析：
     * 1、创建线程池
     * 2、通过循环提交8个任务
     * 3、前三个任务会被放入核心线程里面执行
     * 4、当4，5任务来的时候，此时3个核心线程还在工作，所以将他们放到任务队列中去
     * 5、当第6任务来的时候此时核心线程满了，队列也满了，所以判断当前工作线程数是否大于maximumPoolSize，如果不大于，则为任务创建线程
     * 6、当任务7，8，提交时，同5操作一样，创建线程
     * 7、当任务1执行完后，此时线程不会被销毁，获取workQueue任务队列里面的4任务执行
     * 8、当任务2执行完后，此时线程不会被销毁，获取workQueue任务队列里面的5任务执行
     * 假设队列满了，并且所有的线程仍在执行，此时在提交任务，则会抛出异常RejectedExecutionException
     */
}
